#pragma once

#include "Noncopyable.h"
#include "InetAddress.h"
#include "Callbacks.h"
#include "Buffer.h"
#include "Timestamp.h"

#include <memory>
#include <string>
#include <atomic>

class Channel;
class Socket;
class EventLoop;

/*
*   TcpServer => Acceptor => 有一个新用户连接，通过accept函数拿到connfd
*   这个connfd包装成TcpConnection 设置回调 => Channel => Poller => Channel的回调操作
*/
// enable_shared_from_this:能安全的获得this指针
class TcpConnection : noncopyable,public std::enable_shared_from_this<TcpConnection>
{
public:
    TcpConnection(EventLoop* loop,
                const std::string &nameArg,
                int sockfd,
                const InetAddress localAddr,
                const InetAddress peerAddr);
    ~TcpConnection();

    EventLoop* getLoop() const { return loop_; }
    const std::string name() const { return name_; }
    const InetAddress& localAddress() const { return localAddr_; }
    const InetAddress& perrAddress() const { return peerAddr_; }

    bool connected() const { return state_ == kConnected; }

    // 发送数据
    // void send(const void* message,int len);
    void send(const std::string& buf);

    // 关闭连接
    void shutdown();

    void setConnectionCallback(const ConnectionCallback& cb) { connectionCallback_ = cb; }
    void setMessageCallback(const MessageCallback& cb) { messageCallback_ = cb; }
    void setWriteCompleteCallback(const WriteCompleteCallback& cb) { writeCompleteCallback_ = cb; }
    void setHighWaterMarkCallback(const HighWaterMarkCallback& cb,size_t highWaterMark) 
    { highWaterMarkCallback_ = cb; highWaterMark_ = highWaterMark;  }
    void setCloseCallback(const CloseCallback& cb) { closeCallback_ = cb; }

    // 连接建立
    void connectEstablished();
    // 连接销毁
    void connectDestroyed();

private:
    // 已经断开了，正在连接，已经连接上了，正在断开连接
    enum StateE {kDisconnected,kConnecting,kConnected,kDisconnecting};
    void setState(StateE state) { state_ = state; }

    void handleRead(Timestamp receiveTime);
    void handleWrite();
    void handleClose();
    void handleError();


    void sendInLoop(const void* data,size_t len);
    void shutdownInLoop();

    EventLoop* loop_; // 这里绝对不是baseLoop，因为TcpConnection都是在subLoop里面管理的
    const std::string name_;
    std::atomic_int state_;
    bool reading_;

    // 这里和Accept类似    Accept=》mainLoop    TcpConnection=》subLoop
    std::unique_ptr<Socket> socket_;
    std::unique_ptr<Channel> channel_;

    const InetAddress localAddr_;
    const InetAddress peerAddr_;

    ConnectionCallback connectionCallback_; // 有新连接事件的回调
    MessageCallback messageCallback_; // 有读写消息的回调
    WriteCompleteCallback writeCompleteCallback_;  // 消息发送完成以后的回调
    HighWaterMarkCallback highWaterMarkCallback_;
    CloseCallback closeCallback_;

    size_t highWaterMark_; // 水位标志

    Buffer inputBuffer_; // 接收数据的缓冲区
    Buffer outputBuffer_; // 发送数据的缓冲区
};